#include "applicationnative.h"
#include <optra/applicationinfo.h>
#include <optra/appoptrainfo.h>
#include <QLibrary>
#include <optra/common/proxy.h>
#include "application.h"
#include "scene.h"

#include <pch.h>

typedef int (*Prototype)(ApplicationInfo**);
typedef int (*Prototype2)(Optra::AppOptraInfo*);
typedef int (*Prototype3)(QWidget**);

extern Optra::Proxy* proxy;

ApplicationNative::ApplicationNative(const QString& appname, Application* app, QObject *parent) :
    Task(appname, parent), appname_(appname), app_(app)
{
}


void ApplicationNative::run()
{
    setCanRemove(false);
    emit state(QString("Initialize: %1").arg(appname_), Optra::LogEvent::debug);
    QDir d = proxy->directory(Optra::Proxy::applications);
    d.cd(appname_);


    QLibrary lib(d.absoluteFilePath(appname_));
    if (!lib.load()){
        emit state(QString("Application load error: %1").arg(appname_), Optra::LogEvent::warning);
        setCanRemove(true);
        return;
    }

    ApplicationInfo *appinfo = NULL;
    Prototype3 p = (Prototype3)lib.resolve("entry");
    if (!p){
        emit state(QString("no valid application: %1").arg(appname_), Optra::LogEvent::critical);
        setCanRemove(true);
        return;
    }

    try{
        QWidget *window = 0;
        p(&window);
        if (window){
            //window->show();
            QGraphicsProxyWidget* pw = new QGraphicsProxyWidget(0, Qt::Dialog);
            pw->setWidget(window);
            pw->setZValue(63);
            app_->primaryScene()->addItem(pw);
        }
    }catch(...){
        emit state(QString("application exception: %1").arg(appname_), Optra::LogEvent::critical);
        setCanRemove(true);
    }

    emit state(QString("Application done: %1").arg(appname_), Optra::LogEvent::info);
    setCanRemove(true);
}
